package written;

import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;

/**
 * //评测题目: 用多个线程交替打印字符，如字符串"ali"，如一个线程打印a，一个线程打印l，一个线程打印i ，
 * //一个线程打印空格，如：ali ali ali ...
 * //代码支持拓展，能打印任意字符串"alibaba"，如：alibaba alibaba alibaba alibaba ...
 *
 * @author TANGYE
 * @date 2021-01-06 21:14
 **/
public class QuestionFive implements Runnable {

    private static Lock lock = new ReentrantLock();

    private static List<Condition> conditionList = new ArrayList<>();

    private static int num = 1;

    private final static int MAX = 100;

    // 自己需要打印的字母
    private String zm;

    Condition condition;

    // 应该唤醒的condition下标
    private int notifyIndex;

    private int len;

    private int mod;

    public QuestionFive(String zm, Condition condition, int notifyIndex, int len) {
        this.zm = zm;
        this.condition = condition;
        this.notifyIndex = notifyIndex;
        this.len = len;
        this.mod = notifyIndex;
    }

    @Override
    public void run() {
        try {
            lock.lock();
            while (num < MAX) {
                if (num % len != mod) {
                    condition.await();
                }
                System.out.print(zm);
                num++;
                conditionList.get(notifyIndex).signal();
            }
            conditionList.get(notifyIndex).signal();
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            lock.unlock();
        }

    }


    public static void main(String[] args) {

        String str = "alibab";
        List<Thread> threads = new ArrayList<>(30);
        char[] chars = str.toCharArray();
        int len = chars.length;

        for (int i = 0; i < chars.length; i++) {
            String zm = String.valueOf(chars[i]);
            Condition condition = lock.newCondition();
            Thread thread = new Thread(new QuestionFive(zm, condition, i + 1, len + 1), "Thread-" + zm);
            conditionList.add(condition);
            threads.add(thread);
        }

        Condition condition = lock.newCondition();
        Thread thread = new Thread(new QuestionFive(" ", condition, 0, len + 1), "Thread-Black");
        threads.add(thread);
        conditionList.add(condition);
        threads.forEach(t -> t.start());

    }


}
